/**
 * 该函数接受一个或多个数字参数，并返回它们的乘积。
 * 它使用展开运算符 (...args) 来接收参数，允许传递任意数量的数字。
 * 函数内部使用数组的 reduce 方法来累积参数的乘积。
 * 初始累积值设为 1，以确保当没有传递任何参数时返回值为 1，而不是 0。
 *
 * @param args 一个或多个要相乘的数字。
 * @returns 所有传入数字的乘积。如果没有传入任何数字，则返回 1。
 */
export function multiply(...args : number[]) : number {
    if (args.length === 0) {
        return 1;
    } else if (args.length === 1) {
        return args[0];
    }
    return args.reduce( (acc, cur) => acc * cur, args[0] );
}

/**
 * 分割函数，用于将一系列数字连续相除
 *
 * 此函数接受一个数字数组作为参数，然后将这些数字连续相除
 * 它使用reduce方法来迭代数组中的每个元素，将当前值与累加器相除
 * 如果数组为空，函数将返回1，作为没有提供任何数字时的默认结果
 *
 * @param args 数字数组，其中包含要相除的一系列数字
 * @returns 数字，表示连续相除的结果
 */
export function divide(...args : number[]) : number {
    return args.reduce( (acc, cur) => acc / cur, 1 );
}

/**
 * 函数subtract用于计算一组数字的差值。
 * 它接受一个或多个数字作为参数，依次从第一个数字中减去后续的数字。
 *
 * @param args - 一个或多个数字，将被依次相减。
 * @returns 返回所有输入数字依次相减的结果。
 */
export function subtract(...args : number[]) : number {
    // 使用数组的reduce方法来依次减去数组中的每个数字。
    // 初始值为0，确保如果没有提供任何数字，返回值为0。
    return args.reduce( (acc, cur) => acc - cur, 100 );
}

/**
 * 计算一组数字的总和
 *
 * 此函数使用展开运算符 (...args) 来接受一个数字数组作为参数，从而计算它们的总和
 * 它通过调用数组的 reduce 方法来累加数组中的所有元素，初始值为0
 *
 * @param args 数字数组，包含需要相加的数字
 * @returns 数组中数字的总和
 */
export function sum(...args : number[]) : number {
    return args.reduce( (acc, cur) => acc + cur, 0 );
}

/**
 * 计算一组数字的平均值
 *
 * 此函数使用展开运算符 (...args) 来接受一个数字数组作为参数，从而计算它们的平均值
 * 它通过调用 sum 函数来计算数组中所有数字的总和，然后将总和除以数组的长度来获得平均值
 *
 * @param args 数字数组，包含需要计算平均值的数字
 * @returns 数组中数字的平均值
 */
export function average(...args : number[]) : number {
    return sum(...args) / args.length;
}

export function factorial(num : number) : number {
    if (num < 0) {
        throw new Error('Factorial is not defined for negative numbers.');
    }
    if (num === 0 || num === 1) {
        return 1;
    }
    return num * factorial(num - 1);
}